home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / GUSI / Examples / GUSIINETTest.c < prev    next >
Text File  |  1993-08-25  |  9KB  |  437 lines

  1. /*********************************************************************
  2. File        :    GUSI                -    Grand Unified Socket Interface
  3. File        :    GUSIINETTest    -    Test unix domain sockets
  4. Author    :    Matthias Neeracher <neeri@iis.ethz.ch>
  5. Started    :    02Sep92
  6. Modified    :    08Sep92    MN    First attempt
  7.                 08Sep92    MN    Factor out common socket routines
  8.                 14Sep92    MN    Misinterpreted hostent structure
  9.                 03Mar93    MN    Added performance test
  10.                 29Jul93    MN    servent tests
  11.                 25Aug93    MN    gethostbyaddr()
  12. Last        :    25Aug93
  13. *********************************************************************/
  14.  
  15. #include <GUSI.h>
  16. #include <GUSITest.h>
  17. #include <stdio.h>
  18. #include <fcntl.h>
  19. #include <stdlib.h>
  20. #include <errno.h>
  21. #include <string.h>
  22.  
  23. #include "Events.h"
  24.  
  25. extern int GUSIDefaultSpin(spin_msg, long);
  26.  
  27. char    addrstr[100];
  28.  
  29. void Socket(char ch1, char, const char *)
  30. {
  31.     sock    =    socket(AF_INET, (ch1 == 's') ? SOCK_STREAM : SOCK_DGRAM, 0);
  32.     
  33.     if (sock == -1)    {
  34.         printf("# socket() returned error %s\n", Explain());
  35.         Where();
  36.     }
  37. }
  38.  
  39. void Bind(char ch1, char ch2, const char * cmd)
  40. {
  41.     int                        len;
  42.     struct sockaddr_in    addr;
  43.  
  44.     if (sock == -1)    {
  45.         printf("# socket is not open\n");
  46.         Where();
  47.         
  48.         return;
  49.     }
  50.  
  51.     if (sscanf(cmd, "%s %hd", addrstr, &addr.sin_port) == 2) {
  52.         addr.sin_addr            =    inet_addr(addrstr);
  53.         addr.sin_family        =    AF_INET;
  54.         len                        =    sizeof(struct sockaddr_in);
  55.     } else {
  56.         Usage(ch1, ch2);
  57.         return;
  58.     }
  59.     
  60.     if (bind(sock, (struct sockaddr *) &addr, len))    {
  61.         printf(
  62.             "bind(%s:%d) returned error %s\n", 
  63.             inet_ntoa(addr.sin_addr),
  64.             addr.sin_port, 
  65.             Explain());
  66.             
  67.         Where();
  68.     }
  69. }
  70.  
  71. void Accept(char, char, const char *)
  72. {
  73.     int                        len;
  74.     struct sockaddr_in    addr;
  75.  
  76.     if (sock == -1)    {
  77.         printf("# socket is not open\n");
  78.         Where();
  79.         
  80.         return;
  81.     }
  82.     if (accsock != -1)    {
  83.         printf("# can't accept more than one connection\n");
  84.         Where();
  85.         
  86.         return;
  87.     }
  88.  
  89.     len    =    sizeof(struct sockaddr_in);
  90.     sock    =    accept(accsock = sock, (struct sockaddr *) &addr, &len);
  91.     
  92.     if (sock < 0)    {
  93.         printf("# accept() returned error %s\n", Explain());
  94.         sock        =    accsock;
  95.         accsock    =    -1;
  96.     } else {
  97.         printf(
  98.             "# accepted connection from %s port %d\n", 
  99.             inet_ntoa(addr.sin_addr), 
  100.             addr.sin_port);
  101.     }
  102.     
  103.     Where();
  104. }
  105.     
  106. void Connect(char ch1, char ch2, const char * cmd)
  107. {
  108.     int                        len;
  109.     struct sockaddr_in    addr;
  110.  
  111.     if (sock == -1)    {
  112.         printf("# socket is not open\n");
  113.         Where();
  114.         
  115.         return;
  116.     }
  117.     
  118.     if (sscanf(cmd, "%s %hd", addrstr, &addr.sin_port) == 2) {
  119.         addr.sin_addr            =    inet_addr(addrstr);
  120.         addr.sin_family        =    AF_INET;
  121.         len                        =    sizeof(struct sockaddr_in);
  122.     } else {
  123.         Usage(ch1, ch2);
  124.         return;
  125.     }
  126.  
  127.     if (connect(sock, (struct sockaddr *) &addr, len))    {
  128.         printf(
  129.             "connect(%s:%d) returned error %s\n", 
  130.             inet_ntoa(addr.sin_addr),
  131.             addr.sin_port, 
  132.             Explain());
  133.         Where();
  134.     }
  135. }    
  136.  
  137. int ReadWhileUCan()
  138. {
  139.     int                res;
  140.     char *            outline;
  141.     fd_set            rdfds;
  142.     fd_set            exfds;
  143.     struct timeval    delay;
  144.     char                 out[500];
  145.  
  146.     for (;;) {
  147.         FD_ZERO(&rdfds);
  148.         FD_ZERO(&exfds);
  149.         
  150.         FD_SET(sock, &rdfds);
  151.         FD_SET(sock, &exfds);
  152.         
  153.         delay.tv_sec    =    1;
  154.         delay.tv_usec    =    0;
  155.         
  156.         res = select(sock+1, &rdfds, nil, &exfds, &delay);
  157.         
  158.         if (res < 0)    {
  159.             printf("# select() returned error %s\n", Explain());
  160.             
  161.             return -1;
  162.         } else if (!res)
  163.             return 0;
  164.         else if (res && FD_ISSET(sock, &exfds)) {
  165.             printf("# select() returned an exception\n");
  166.             
  167.             return -1;
  168.         } else if (res && FD_ISSET(sock, &rdfds)) {
  169.             res = read(sock, out, 500);
  170.             
  171.             if (res < 0) {
  172.                 printf("# read() returned error %s\n", Explain());
  173.             
  174.                 return -1;
  175.             }
  176.             
  177.             out[res] = 0;
  178.             
  179.             for (outline = strtok(out, "\n\r"); outline; outline = strtok(nil, "\n\r"))
  180.                 printf("%s\n", outline);
  181.         }
  182.     }
  183. }
  184.  
  185. void Telnet(char, char, const char *)
  186. {
  187.     int                len;
  188.     int                 part;
  189.     int                res;
  190.     char *            line;
  191.     char *            outline;
  192.     fd_set            rdfds;
  193.     fd_set            wrfds;
  194.     fd_set            exfds;
  195.     struct timeval    delay;
  196.     char                 in[100];
  197.     char                 out[500];
  198.     
  199.     if (sock == -1)    {
  200.         printf("# socket is not open\n");
  201.         Where();
  202.             
  203.         return;
  204.     }
  205.  
  206.     printf("# Entering Poor Man's Telnet mode\n");
  207.     
  208.     for (;;) {
  209.         if (ReadWhileUCan())
  210.             break;
  211.         
  212.         Prompt();
  213.         
  214.         if (!fgets(in, 100, input))
  215.             break;
  216.             
  217.         ++inputline;
  218.         
  219.         if (!strcmp(in, ".\n"))
  220.             break;
  221.         
  222.         if (!strcmp(in, "?\n"))
  223.             continue;
  224.  
  225.         len             = strlen(in);
  226.         in[len++]    = '\r';
  227.         in[len]        = 0;
  228.         
  229.         for (line = in; len; len -= part, line += part) {        
  230.             part = 0;
  231.  
  232.             FD_ZERO(&rdfds);
  233.             FD_ZERO(&wrfds);
  234.             FD_ZERO(&exfds);
  235.             
  236.             FD_SET(sock, &rdfds);
  237.             FD_SET(sock, &wrfds);
  238.             FD_SET(sock, &exfds);
  239.             
  240.             delay.tv_sec    =    10;
  241.             delay.tv_usec    =    0;
  242.             
  243.             res = select(sock+1, &rdfds, &wrfds, &exfds, &delay);
  244.             
  245.             if (res < 0)    {
  246.                 printf("# select() returned error %s\n", Explain());
  247.                 
  248.                 return;
  249.             } else if (!res) {
  250.                 printf("# select() timed out\n");
  251.                 
  252.                 return;
  253.             } else if (FD_ISSET(sock, &exfds)) {
  254.                 printf("# select() returned an exception\n");
  255.                 
  256.                 return;
  257.             }
  258.             
  259.             if (FD_ISSET(sock, &rdfds)) {
  260.                 res = read(sock, out, 500);
  261.                 
  262.                 if (res < 0) {
  263.                     printf("# read() returned error %s\n", Explain());
  264.                 
  265.                     return;
  266.                 }
  267.                 
  268.                 out[res] = 0;
  269.                 
  270.                 for (outline = strtok(out, "\n\r"); outline; outline = strtok(nil, "\n\r"))
  271.                     printf("%s\n", outline);
  272.             } else if (FD_ISSET(sock, &wrfds)) {
  273.                 res = write(sock, line, len);
  274.             
  275.                 if (res < 0) {
  276.                     line[strlen(line) - 2] = 0;
  277.                     printf("# write(\"%s\") returned error %s\n", line, Explain());
  278.                 
  279.                     return;
  280.                 }
  281.                 
  282.                 part = res;
  283.             }
  284.         }
  285.     }
  286.     
  287.     printf("# Leaving Poor Man's Telnet mode\n");
  288. }
  289.  
  290. void N2Addr(char ch1, char ch2, const char * cmd)
  291. {
  292.     struct in_addr        addr;
  293.     struct hostent *    ent;
  294.     
  295.     if (sscanf(cmd, "%s", addrstr) == 1)
  296.         if (ent = gethostbyname(addrstr)) {
  297.             memcpy(&addr, ent->h_addr, sizeof(struct in_addr));
  298.             printf("# gethostbyname(%s) returned %s\n", addrstr, inet_ntoa(addr));
  299.         } else
  300.             printf("# gethostbyname(%s) failed.\n", addrstr);
  301.     else
  302.         Usage(ch1, ch2);
  303. }
  304.  
  305. void A2Name(char ch1, char ch2, const char * cmd)
  306. {
  307.     struct in_addr        addr;
  308.     struct hostent *    ent;
  309.     
  310.     if (sscanf(cmd, "%s", addrstr) == 1) {
  311.         addr = inet_addr(addrstr);
  312.         if (ent = gethostbyaddr((char *) &addr, 0, 0)) {
  313.             printf("# gethostbyaddr(%s) returned %s\n", addrstr, ent->h_name);
  314.         } else
  315.             printf("# gethostbyaddr(%s) failed.\n", addrstr);
  316.     } else
  317.         Usage(ch1, ch2);
  318. }
  319.  
  320. void PerfTest(char ch1, char ch2, const char * cmd)
  321. {
  322.     int     count;
  323.     int     i;
  324.     long    ticks;
  325.     char    buf[1024];
  326.     
  327.     if (sock == -1)    {
  328.         printf("# socket is not open\n");
  329.         Where();
  330.             
  331.         return;
  332.     }
  333.  
  334.     if (sscanf(cmd, "%d", &count) == 1) {
  335.         ticks = TickCount();
  336.         for (i=0; i<count; i++) {
  337.             write(sock, buf, 1);
  338.             read(sock, buf, 1024);
  339.         } 
  340.         printf("# Did %d iterations in %d ticks.\n", count, TickCount()-ticks);
  341.     } else
  342.         Usage(ch1, ch2);
  343. }
  344.  
  345. void ServByName(char ch1, char ch2, const char * cmd)
  346. {
  347.     struct servent *    ent;
  348.     char                    proto[6];
  349.     
  350.     if (sscanf(cmd, "%s %s", addrstr, proto) == 2)
  351.         if (ent = getservbyname(addrstr, proto))
  352.             printf("# getservbyname(%s %s) returned %d\n", addrstr, proto, ent->s_port);
  353.         else
  354.             printf("# getservbyname(%s %s) failed.\n", addrstr, proto);
  355.     else if (sscanf(cmd, "%s", addrstr) == 1)
  356.         if (ent = getservbyname(addrstr, NULL))
  357.             printf("# getservbyname(%s) returned %d\n", addrstr, ent->s_port);
  358.         else
  359.             printf("# getservbyname(%s) failed.\n", addrstr);
  360.     else
  361.         Usage(ch1, ch2);
  362. }
  363.  
  364. void PrintServEnt(struct servent * ent, Boolean full)
  365. {
  366.     char    ** al;
  367.     
  368.     printf("%s", ent->s_name);
  369.     
  370.     if (full)
  371.          printf(" %d/%s", ent->s_port, ent->s_proto);
  372.         
  373.     for (al = ent->s_aliases; *al; ++al)
  374.         printf(" %s", *al);
  375.     
  376.     putchar('\n');
  377. }
  378.  
  379. void ServByPort(char ch1, char ch2, const char * cmd)
  380. {
  381.     int                    port;
  382.     struct servent *    ent;
  383.     char                    proto[6];
  384.     
  385.     if (sscanf(cmd, "%d %s", &port, proto) == 2)
  386.         if (ent = getservbyport(port, proto)) {
  387.             printf("# getservbyport(%d %s) returned ", port, proto);
  388.             
  389.             PrintServEnt(ent, false);
  390.         } else
  391.             printf("# getservbyport(%d %s) failed.\n", addrstr, proto);
  392.     else if (sscanf(cmd, "%d %s", &port) == 1)
  393.         if (ent = getservbyport(port, NULL)) {
  394.             printf("# getservbyport(%d) returned ", port);
  395.             
  396.             PrintServEnt(ent, false);
  397.         } else
  398.             printf("# getservbyport(%d) failed.\n", addrstr);
  399.     else
  400.         Usage(ch1, ch2);
  401. }
  402.  
  403. void ServList(char, char, const char *)
  404. {
  405.     struct servent *    ent;
  406.     
  407.     setservent(0);
  408.     
  409.     while (ent = getservent()) {
  410.         printf("# ");
  411.         PrintServEnt(ent, true);
  412.     }
  413. }
  414.  
  415. main(int argc, char ** argv)
  416. {
  417.     printf("GUSIINETTest        MN 25Aug93\n\n");
  418.  
  419.     COMMAND('s', 's', Socket,  "",                 "Create a stream socket");
  420.     COMMAND('d', 's', Socket,  "",                 "Create a datagram socket");
  421.     COMMAND('b', 'd', Bind,      "addr port",     "Bind to address");
  422.     COMMAND('c', 'o', Connect, "addr port",     "Connect to address");
  423.     COMMAND('a', 'c', Accept,  "",                 "Accept a connection");
  424.     COMMAND('t', 'n', Telnet,  "",                "Play telnet");
  425.     COMMAND('n', 'a', N2Addr,    "name",            "Convert name to address");
  426.     COMMAND('a', 'n', A2Name,    "addr",            "Convert address to name");
  427.     COMMAND('p', 't', PerfTest,"count",            "Do a performance test");
  428.     COMMAND('s', 'n', ServByName, "name",        "Convert service name to port number");
  429.     COMMAND('s', 'p', ServByPort, "port",        "Convert port number to service name");
  430.     COMMAND('s', 'l', ServList, "",                "List services");
  431.     
  432.     AddSocketCommands();
  433.     
  434.     GUSISetEvents(GUSISIOWEvents);
  435.     RunTest(argc, argv);
  436.     CleanupSockets();
  437. }